package com.sls.game.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.ServerDateAndTime;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.assist.Helper;
import com.sls.game.common.DeductionRefund;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsOrderLogDAO;
import com.sls.game.parser.sls.OrderStatusSendParse;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.DownstreamUserInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.GoodsOrderLog;
import com.sls.game.pojo.NutsNetOrderStatusInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.service.NutsNetOrderStatusService;

/**
 * 
 * @description 异步充值订单状态变化通知接口
 * @author Wangxuegang
 * @date 2012-9-5
 * 
 */
@Service("nutsNetOrderStatusService")
public class NutsNetOrderStatusServiceImpl implements NutsNetOrderStatusService {
	private static Logger log = Logger
			.getLogger(NutsNetOrderStatusServiceImpl.class);

	private Gson gson = null;

	/**
	 * 网游充值订单表DAO
	 */
	private GoodsOrderDAO goodsOrderDAO;

	private GoodsOrderLogDAO goodsOrderLogDAO;

	private DownstreamUserDAO downstreamUserDAO;

	public DownstreamUserDAO getDownstreamUserDAO() {
		return downstreamUserDAO;
	}

	@Resource(name = "downstreamUserDAO")
	public void setDownstreamUserDAO(DownstreamUserDAO downstreamUserDAO) {
		this.downstreamUserDAO = downstreamUserDAO;
	}

	public GoodsOrderLogDAO getGoodsOrderLogDAO() {
		return goodsOrderLogDAO;
	}

	@Resource(name = "goodsOrderLogDAO")
	public void setGoodsOrderLogDAO(GoodsOrderLogDAO goodsOrderLogDAO) {
		this.goodsOrderLogDAO = goodsOrderLogDAO;
	}

	public GoodsOrderDAO getGoodsOrderDAO() {
		return goodsOrderDAO;
	}

	@Resource(name = "goodsOrderDAO")
	public void setGoodsOrderDAO(GoodsOrderDAO goodsOrderDAO) {
		this.goodsOrderDAO = goodsOrderDAO;
	}

	public NutsNetOrderStatusServiceImpl() {
		gson = CommonUtil.gson();
	}

	/**
	 * 异步充值订单状态变化通知接口
	 * 
	 * @param body
	 * @param head
	 * @return
	 * @throws ServerDisponseException
	 */
	@Override
	public String insert(String body, Head head) throws ServerDisponseException {
		if (log.isInfoEnabled()) {
			log.info("进入Service开始处理[" + head.getRequestId() + "]的请求");
		}
		// 对消息body进行解析
		NutsNetOrderStatusInfo info = gson.fromJson(body,
				NutsNetOrderStatusInfo.class);
		boolean flag = checkDataOfInsert(info);

		// 订单处理结果主动给下游
		String userhandleResult = sendUserOrderStatusMsg(info, head);

		if (flag) { // 数据校验通过
			// 更新订单表
			updateGoodsorder(head, info, userhandleResult);
		}

		return null;
	}

	/**
	 * 主动给下游
	 * 
	 * @param info
	 * @return
	 */
	private String sendUserOrderStatusMsg(NutsNetOrderStatusInfo info, Head head) {
		String handleResult = "FAILED";
		// 下游回调地址
		String notifyUrl = null;
		// 下游用户编号
		String contractId = null;
		// 手拉手订单编号
		String ptOrderNo = info.getPtOrderNo();
		GoodsOrderInfo goodsOrderInfo = null;
		goodsOrderInfo = goodsOrderDAO.queryNotifyUrlByOrderId(ptOrderNo);
		if (goodsOrderInfo != null) {
			notifyUrl = goodsOrderInfo.getNotifyUrl();
			contractId = goodsOrderInfo.getContractId();
		}

		String secretKey = null; // 下游用户密钥
		DownstreamUserInfo downstreamUserInfo = null;
		downstreamUserInfo = downstreamUserDAO.queryUserByUserNO(contractId);
		if (downstreamUserInfo != null) {
			secretKey = downstreamUserInfo.getSecretKey();
		}

		String parameter = obtainParameter(info, goodsOrderInfo, secretKey);
		String url = notifyUrl + "?" + parameter;
		HttpClient httpClient = new HttpClient();
		// 供应商返回消息编码方式
		String supplyEncode = "UTF-8";
		try {
			log.info("请求ID：" + head.getRequestId() + "，手拉手异步回调给下游用户的url：" + url);
			// 给下游发消息
			String xmlStr = httpClient.doGet(url, supplyEncode);
			log.info("请求ID：" + head.getRequestId() + "，下游用户的返回结果：" + xmlStr);
			if (xmlStr != null && !("".equals(xmlStr))) {
				SLSHttpInterfaceInfo slsInfo = null;
				slsInfo = OrderStatusSendParse.readUserSendMsg(xmlStr);
				if (slsInfo != null) {
					handleResult = slsInfo.getHandleResult();
				}
			}
		} catch (Exception e) {
			log.error(e);
		}

		return handleResult;
	}

	/**
	 * 创建参数字符串
	 * 
	 * @param info
	 * @param goodsOrderInfo
	 * @return
	 */
	private String obtainParameter(NutsNetOrderStatusInfo info,
			GoodsOrderInfo goodsOrderInfo, String secretKey) {
		// 下游用户订单号
		String ptOrderNo = goodsOrderInfo.getMerchantOrderId();
		// 手拉手订单号
		String supOrderNo = info.getPtOrderNo();
		// 充值后状态
		String status = info.getStatus();
		// 成功处理时间
		String supOrderSuccessTime = info.getSupOrderSuccessTime();
		// 失败原因
		String failedReason = info.getFailedReason();

		log.info("坚果网络异步订单处理结果：" + "\n合作平台编号:" + info.getPartnerId()
				+ "\n合作方平台订单编号:" + ptOrderNo + "\nSUP平台订单号:" + supOrderNo
				+ "\n订单结果:" + status + "\nSUP平台充值成功时间:" + supOrderSuccessTime
				+ "\n失败代码:" + info.getFailedCode() + "\n失败原因:" + failedReason);

		StringBuilder strBui = new StringBuilder();
		strBui.append("ptOrderNo=");
		strBui.append(ptOrderNo);
		strBui.append("&");
		strBui.append("supOrderNo=");
		strBui.append(supOrderNo);
		strBui.append("&");
		strBui.append("status=");
		strBui.append(status);
		if ("ORDER_SUCCESS".equals(status)) { // 成功
			strBui.append("&");
			strBui.append("supOrderSuccessTime=");
			strBui.append(supOrderSuccessTime);
		} else if ("ORDER_FAILED".equals(status)) { // 失败
			strBui.append("&");
			strBui.append("failedReason=");
			String fr = "";
			try {
				if (failedReason != null && !("".equals(failedReason))) {
					fr = URLEncoder.encode(failedReason, "UTF-8");
				}
			} catch (UnsupportedEncodingException e) {
				log.error(e);
			}

			strBui.append(fr);
		}

		strBui.append("sign=");
		String sign = createSign(ptOrderNo, supOrderNo, status,
				supOrderSuccessTime, failedReason, secretKey);
		strBui.append(sign);
		log.info("异步发送给下游用户的订单处理结果    \n 合作方订单编号:" + ptOrderNo + "\n 本地订单编号:"
				+ supOrderNo + "\n 订单最终处理结果：" + status + "\n订单处理的时间:"
				+ supOrderSuccessTime + "\n失败原因：" + failedReason);

		String result = strBui.toString().trim();
		return result;
	}

	/**
	 * 创建签名字符串
	 * 
	 * @param ptOrderNo
	 * @param supOrderNo
	 * @param status
	 * @param supOrderSuccessTime
	 * @return
	 */
	private String createSign(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String failedReason,
			String secretKey) {
		StringBuilder strBui = new StringBuilder();
		strBui.append(ptOrderNo);
		strBui.append(supOrderNo);
		strBui.append(status);
		if (supOrderSuccessTime != null && !("".equals(supOrderSuccessTime))) {
			strBui.append(supOrderSuccessTime);
		}
		if (failedReason != null && !("".equals(failedReason))) {
			strBui.append(failedReason);
		}

		strBui.append(secretKey);
		String data = strBui.toString().trim();
		String result = null;
		result = UtilMD5Encryption.createMD5Encryption(data);

		return result;
	}

	/**
	 * 根据交易返回的结果更新订单表
	 * 
	 * @param head
	 * 
	 * @param info
	 * 
	 */
	private void updateGoodsorder(Head head, NutsNetOrderStatusInfo info,
			String userhandleResult) {
		// 手拉手订单编号
		String ptOrderNo = info.getPtOrderNo();
		// SUP平台订单号
		String supOrderNo = info.getSupOrderNo();
		// 订单结果
		String status = info.getStatus();
		// SUP平台充值成功时间
		String supOrderSuccessTime = info.getSupOrderSuccessTime();

		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setOrderId(ptOrderNo);
		goodsOrderInfo.setSupOrderId(supOrderNo);
		goodsOrderInfo.setResult(status);

		String statusValue = "1";
		if ("ORDER_SUCCESS".equals(status)) { // 成功
			statusValue = "1";
		} else if ("ORDER_FAILED".equals(status)) { // 失败
			statusValue = "0";
			// 退款操作
			DeductionRefundInfo dedInfo = null;
			dedInfo = DeductionRefund.refundWhenAsynCallBackFailed(ptOrderNo,
					goodsOrderDAO, head);
			String paymentStatus = "";
			if (dedInfo != null) {
				paymentStatus = dedInfo.getPaymentStatus();
			}

			if ("1".equals(paymentStatus)) { // 成功
				goodsOrderInfo.setIsPay("3"); // 退款成功

				// 退款成功，通知下游用户
				DeductionRefund.noticeUserRefundMsg(ptOrderNo, dedInfo,
						goodsOrderDAO, downstreamUserDAO, goodsOrderLogDAO);

			} else if ("2".equals(paymentStatus)) {
				GoodsOrderInfo orderInfo = goodsOrderDAO
						.queryByOrderId(ptOrderNo);
				if (orderInfo != null) {
					String isPayValue = orderInfo.getIsPay(); // 支付状态值
					if ("1".equals(isPayValue)) {
						goodsOrderInfo.setIsPay("2"); // 退款失败
					}
				}
			}
		}
		goodsOrderInfo.setStatus(statusValue);
		goodsOrderInfo.setSupOrderSuccessTime(supOrderSuccessTime);
		goodsOrderInfo.setUserhandleResult(userhandleResult);
		goodsOrderInfo.setSynOrAsy("1");// 异步推送

		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

		// 写订单日志
		try {
			String orderId = ptOrderNo;
			GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				this.goodsOrderLogDAO.insert(orderLog);
			}

		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
	}

	/**
	 * 数据校验
	 * 
	 * @param info
	 */
	private boolean checkDataOfInsert(NutsNetOrderStatusInfo info) {
		boolean flag = false;
		// 合作平台编号
		String partnerId = info.getPartnerId();
		// 合作方平台订单编号
		String ptOrderNo = info.getPtOrderNo();
		// SUP平台订单号
		String supOrderNo = info.getSupOrderNo();
		// 订单结果
		String status = info.getStatus();
		// 签名字符串
		String sign = info.getSign();

		if ("".equals(partnerId) || partnerId == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORMNO_NULL.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORMNO_NULL
							.getDescription());
		} else if ("".equals(ptOrderNo) || ptOrderNo == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getDescription());
		} else if ("".equals(supOrderNo) || supOrderNo == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SUP_ORDER_NO_NULL.getCode(),
					ExceptionCodeDes.SUP_ORDER_NO_NULL.getDescription());
		} else if ("".equals(status) || status == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.ORDER_STATUS_NULL.getCode(),
					ExceptionCodeDes.ORDER_STATUS_NULL.getDescription());
		} else if ("".equals(sign) || sign == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SIG_NATURE_NULL.getCode(),
					ExceptionCodeDes.SIG_NATURE_NULL.getDescription());
		} else {
			flag = true;
		}

		return flag;

	}

}
